﻿#pragma once
#include "common.h"
#include <iosfwd>

namespace anip
{
	/// <summary>
	/// Represents an RGBA color with floating-point components
	/// in native color space, used in e.g. GUI and rendering.
	/// </summary>
	struct color
	{
		float r, g, b, a;

		constexpr color():
			r(0), g(0), b(0), a(0) {}

		constexpr color(float _r, float _g, float _b, float _a) :
			r(_r), g(_g), b(_b), a(_a) { }

		constexpr color(float _i) :
			r(_i), g(_i), b(_i), a(_i) { }

		color mulWithoutAlpha(float c) const
		{
			return { r * c, g * c, b * c, a };
		}

		color operator*(float c) const
		{
			return { r * c, g * c, b * c, a * c };
		}
		
		color operator/(float c) const
		{
			return { r / c, g / c, b / c, a / c };
		}

		color operator*(const color& c) const
		{
			return { r * c.r, g * c.g, b * c.b, a * c.a };
		}

		color operator+(const color& c) const
		{
			return { r + c.r, g + c.g, b + c.b, a + c.a };
		}
		
		color operator-(const color& c) const
		{
			return { r - c.r, g - c.g, b - c.b, a - c.a };
		}

		bool operator==(const color& c) const
		{
			return abs(r - c.r) < 0.001f && abs(g - c.g) < 0.001f 
				&& abs(b - c.b) < 0.001f && abs(a - c.a) < 0.001f;
		}

		bool operator!=(const color& c) const
		{
			return !(*this == c);
		}
	};

	template<>
	void binaryWrite(const color& val, std::ostream& o);

	template<>
	void binaryRead(color& val, std::istream& o);

	wstring toString(const color& x);

	class Colors
	{
	public:
		static const color transparent;

		// (0.941, 0.973, 1)
		static const color aliceBlue;
		// (0.98, 0.922, 0.843)
		static const color antiqueWhite;
		// (0, 1, 1)
		static const color aqua;
		// (0.498, 1, 0.831)
		static const color aquamarine;
		// (0.941, 1, 1)
		static const color azure;
		// (0.961, 0.961, 0.863)
		static const color beige;
		// (1, 0.894, 0.769)
		static const color bisque;
		// (0, 0, 0)
		static const color black;
		// (1, 0.922, 0.804)
		static const color blanchedAlmond;
		// (0, 0, 1)
		static const color blue;
		// (0.541, 0.169, 0.886)
		static const color blueViolet;
		// (0.647, 0.165, 0.165)
		static const color brown;
		// (0.871, 0.722, 0.529)
		static const color burlyWood;
		// (0.373, 0.62, 0.627)
		static const color cadetBlue;
		// (0.498, 1, 0)
		static const color chartreuse;
		// (0.824, 0.412, 0.118)
		static const color chocolate;
		// (1, 0.498, 0.314)
		static const color coral;
		// (0.392, 0.584, 0.929)
		static const color cornflowerBlue;
		// (1, 0.973, 0.863)
		static const color cornsilk;
		// (0.863, 0.078, 0.235)
		static const color crimson;
		// (0, 1, 1)
		static const color cyan;
		// (0, 0, 0.545)
		static const color darkBlue;
		// (0, 0.545, 0.545)
		static const color darkCyan;
		// (0.722, 0.525, 0.043)
		static const color darkGoldenrod;
		// (0.663, 0.663, 0.663)
		static const color darkGray;
		// (0, 0.392, 0)
		static const color darkGreen;
		// (0.741, 0.718, 0.42)
		static const color darkKhaki;
		// (0.545, 0, 0.545)
		static const color darkMagenta;
		// (0.333, 0.42, 0.184)
		static const color darkOliveGreen;
		// (1, 0.549, 0)
		static const color darkOrange;
		// (0.6, 0.196, 0.8)
		static const color darkOrchid;
		// (0.545, 0, 0)
		static const color darkRed;
		// (0.914, 0.588, 0.478)
		static const color darkSalmon;
		// (0.561, 0.737, 0.561)
		static const color darkSeaGreen;
		// (0.282, 0.239, 0.545)
		static const color darkSlateBlue;
		// (0.184, 0.31, 0.31)
		static const color darkSlateGray;
		// (0, 0.808, 0.82)
		static const color darkTurquoise;
		// (0.58, 0, 0.827)
		static const color darkViolet;
		// (1, 0.078, 0.576)
		static const color deepPink;
		// (0, 0.749, 1)
		static const color deepSkyBlue;
		// (0.412, 0.412, 0.412)
		static const color dimGray;
		// (0.118, 0.565, 1)
		static const color dodgerBlue;
		// (0.698, 0.133, 0.133)
		static const color fireBrick;
		// (1, 0.98, 0.941)
		static const color floralWhite;
		// (0.133, 0.545, 0.133)
		static const color forestGreen;
		// (1, 0, 1)
		static const color fuchsia;
		// (0.863, 0.863, 0.863)
		static const color gainsboro;
		// (0.973, 0.973, 1)
		static const color ghostWhite;
		// (1, 0.843, 0)
		static const color gold;
		// (0.855, 0.647, 0.125)
		static const color goldenrod;
		// (0.502, 0.502, 0.502)
		static const color gray;
		// (0, 0.502, 0)
		static const color green;
		// (0.678, 1, 0.184)
		static const color greenYellow;
		// (0.941, 1, 0.941)
		static const color honeydew;
		// (1, 0.412, 0.706)
		static const color hotPink;
		// (0.804, 0.361, 0.361)
		static const color indianRed;
		// (0.294, 0, 0.51)
		static const color indigo;
		// (1, 1, 0.941)
		static const color ivory;
		// (0.941, 0.902, 0.549)
		static const color khaki;
		// (0.902, 0.902, 0.98)
		static const color lavender;
		// (1, 0.941, 0.961)
		static const color lavenderBlush;
		// (0.486, 0.988, 0)
		static const color lawnGreen;
		// (1, 0.98, 0.804)
		static const color lemonChiffon;
		// (0.678, 0.847, 0.902)
		static const color lightBlue;
		// (0.941, 0.502, 0.502)
		static const color lightCoral;
		// (0.878, 1, 1)
		static const color lightCyan;
		// (0.98, 0.98, 0.824)
		static const color lightGoldenrodYellow;
		// (0.565, 0.933, 0.565)
		static const color lightGreen;
		// (0.827, 0.827, 0.827)
		static const color lightGrey;
		// (1, 0.714, 0.757)
		static const color lightPink;
		// (1, 0.627, 0.478)
		static const color lightSalmon;
		// (0.125, 0.698, 0.667)
		static const color lightSeaGreen;
		// (0.529, 0.808, 0.98)
		static const color lightSkyBlue;
		// (0.467, 0.533, 0.6)
		static const color lightSlateGray;
		// (0.69, 0.769, 0.871)
		static const color lightSteelBlue;
		// (1, 1, 0.878)
		static const color lightYellow;
		// (0, 1, 0)
		static const color lime;
		// (0.196, 0.804, 0.196)
		static const color limeGreen;
		// (0.98, 0.941, 0.902)
		static const color linen;
		// (1, 0, 1)
		static const color magenta;
		// (0.502, 0, 0)
		static const color maroon;
		// (0.4, 0.804, 0.667)
		static const color mediumAquamarine;
		// (0, 0, 0.804)
		static const color mediumBlue;
		// (0.729, 0.333, 0.827)
		static const color mediumOrchid;
		// (0.576, 0.439, 0.859)
		static const color mediumPurple;
		// (0.235, 0.702, 0.443)
		static const color mediumSeaGreen;
		// (0.482, 0.408, 0.933)
		static const color mediumSlateBlue;
		// (0, 0.98, 0.604)
		static const color mediumSpringGreen;
		// (0.282, 0.82, 0.8)
		static const color mediumTurquoise;
		// (0.78, 0.082, 0.522)
		static const color mediumViolet;
		// (0.098, 0.098, 0.439)
		static const color midnightBlue;
		// (0.961, 1, 0.98)
		static const color mintCream;
		// (1, 0.894, 0.882)
		static const color mistyRose;
		// (1, 0.894, 0.71)
		static const color moccasin;
		// (1, 0.871, 0.678)
		static const color navajoWhite;
		// (0, 0, 0.502)
		static const color navy;
		// (0.992, 0.961, 0.902)
		static const color oldLace;
		// (0.502, 0.502, 0)
		static const color olive;
		// (0.42, 0.557, 0.137)
		static const color oliveDrab;
		// (1, 0.647, 0)
		static const color orange;
		// (1, 0.271, 0)
		static const color orangeRed;
		// (0.855, 0.439, 0.839)
		static const color orchid;
		// (0.933, 0.91, 0.667)
		static const color paleGoldenrod;
		// (0.596, 0.984, 0.596)
		static const color paleGreen;
		// (0.686, 0.933, 0.933)
		static const color paleTurquoise;
		// (0.859, 0.439, 0.576)
		static const color paleVioletRed;
		// (1, 0.937, 0.835)
		static const color papayaWhip;
		// (1, 0.855, 0.725)
		static const color peachPuff;
		// (0.804, 0.522, 0.247)
		static const color peru;
		// (1, 0.753, 0.796)
		static const color pink;
		// (0.867, 0.627, 0.867)
		static const color plum;
		// (0.69, 0.878, 0.902)
		static const color powderBlue;
		// (0.502, 0, 0.502)
		static const color purple;
		// (1, 0, 0)
		static const color red;
		// (0.737, 0.561, 0.561)
		static const color rosyBrown;
		// (0.255, 0.412, 0.882)
		static const color royalBlue;
		// (0.545, 0.271, 0.075)
		static const color saddleBrown;
		// (0.98, 0.502, 0.447)
		static const color salmon;
		// (0.957, 0.643, 0.376)
		static const color sandyBrown;
		// (0.18, 0.545, 0.341)
		static const color seaGreen;
		// (1, 0.961, 0.933)
		static const color seashell;
		// (0.627, 0.322, 0.176)
		static const color sienna;
		// (0.753, 0.753, 0.753)
		static const color silver;
		// (0.529, 0.808, 0.922)
		static const color skyBlue;
		// (0.416, 0.353, 0.804)
		static const color slateBlue;
		// (0.439, 0.502, 0.565)
		static const color slateGray;
		// (1, 0.98, 0.98)
		static const color snow;
		// (0, 1, 0.498)
		static const color springGreen;
		// (0.275, 0.51, 0.706)
		static const color steelBlue;
		// (0.824, 0.706, 0.549)
		static const color tan;
		// (0, 0.502, 0.502)
		static const color teal;
		// (0.847, 0.749, 0.847)
		static const color thistle;
		// (1, 0.388, 0.278)
		static const color tomato;
		// (0.251, 0.878, 0.816)
		static const color turquoise;
		// (0.933, 0.51, 0.933)
		static const color violet;
		// (0.961, 0.871, 0.702)
		static const color wheat;
		// (1, 1, 1)
		static const color white;
		// (0.961, 0.961, 0.961)
		static const color whiteSmoke;
		// (1, 1, 0)
		static const color yellow;
		// (0.604, 0.804, 0.196)
		static const color yellowGreen;

	};
}